package com.baomidou.mybatisplus.criterion;

import java.util.Collection;
import java.util.Collections;

/**
 * 逻辑表达式查询条件，包括and和or 一般表达式组合个数应在2个或者2个以上，否则无需调用此方法，甚至可能出错 (经过改造，现在允许传递过来的QueryCriterion的数组中包含任意多个null)
 * @author Timothy Ren
 */
public class LogicalExpression implements QueryCriterion {

	private static final long serialVersionUID = 1L;
	private final QueryCriterion[] qcArr;
	private final String op;

	/**
	 * 构造方法，其中查询条件个数可变，但一般应在2个或者2个以上，否则无需调用此方法，甚至可能出错
	 * @param op 操作方法（and, or）
	 * @param criterions 可变个数的查询条件
	 */
	protected LogicalExpression(String op, QueryCriterion... criterions) {
		this.op = op;
		this.qcArr = criterions;
	}

	protected LogicalExpression(String op, Collection<QueryCriterion> criterions) {
		this.op = op;
		this.qcArr = criterions.toArray(new QueryCriterion[criterions.size()]);
	}

	/**
	 * 返回查询条件的sql代码
	 * @return String
	 */
	public String toSqlString() {
		if (qcArr == null || qcArr.length == 0) {
			return "";
		} else {
			StringBuffer sb = new StringBuffer("");
			for (int i = 0; i < qcArr.length; i++) {
				if (isValidQueryCriterion(qcArr[i])) {
					// 既不是null也不是空串
					if (sb.length() > 0) {
						sb.append(" ").append(op).append(" ");
					}
					sb.append(qcArr[i].toSqlString());
				}
			}
			if (sb.length() > 0) {
				return (new StringBuffer("(")).append(sb).append(")").toString();
			} else {
				return "";
			}
		}
	}

	/**
	 * 返回查询条件的参数集合
	 * @return Object[]
	 */
	public Object[] getValueArr() {
		if (qcArr == null || qcArr.length == 0) {
			return null;
		} else {
			// 数组长度>=2，将所有的ValueArr组合起来
			int newObjectLen = 0;
			for (int i = 0; i < qcArr.length; i++) {
				if (isValidQueryCriterion(qcArr[i])) {
					newObjectLen += qcArr[i].getValueArr().length;
				}
			}
			if (newObjectLen == 0) {
				return null;
			} else {
				Object[] result = new Object[newObjectLen];
				int position = 0;
				for (int i = 0; i < qcArr.length; i++) {
					if (isValidQueryCriterion(qcArr[i])) {
						System.arraycopy(qcArr[i].getValueArr(), 0, result, position, qcArr[i].getValueArr().length);
						position += qcArr[i].getValueArr().length;
					}
				}
				return result;
			}
		}
	}

	public String toString() {
		if (qcArr == null || qcArr.length == 0) {
			return "";
		} else {
			StringBuffer sb = new StringBuffer("");
			for (int i = 0; i < qcArr.length; i++) {
				if (isValidQueryCriterion(qcArr[i])) {
					// 既不是null也不是空串
					if (sb.length() > 0) {
						sb.append(" ").append(op).append(" ");
					}
					sb.append(qcArr[i].toString());
				}
			}
			if (sb.length() > 0) {
				return (new StringBuffer("(")).append(sb).append(")").toString();
			} else {
				return "";
			}
		}
	}

	/**
	 * 判断是否为有效的查询条件
	 * @param qc QueryCriterion
	 * @return boolean
	 */
	private boolean isValidQueryCriterion(QueryCriterion qc) {
		if (qc != null && !isBlank(qc.toSqlString())) {
			return true;
		} else {
			return false;
		}
	}

	private static boolean isBlank(CharSequence cs) {
		int strLen;
		if (cs == null || (strLen = cs.length()) == 0) {
			return true;
		}
		for (int i = 0; i < strLen; i++) {
			if (Character.isWhitespace(cs.charAt(i)) == false) {
				return false;
			}
		}
		return true;
	}

}
